package com.xrit.sunnyday.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.xrit.sunnyday.dao.MemberDao;
import com.xrit.sunnyday.dao.OrderDao;
import com.xrit.sunnyday.dao.OrderSettingDao;
import com.xrit.sunnyday.exception.SunnydayException;
import com.xrit.sunnyday.pojo.Member;
import com.xrit.sunnyday.pojo.Order;
import com.xrit.sunnyday.pojo.OrderSetting;
import com.xrit.sunnyday.service.OrderService;
import com.xrit.sunnyday.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service(interfaceClass = OrderService.class)
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderSettingDao orderSettingDao;

    @Autowired
    private MemberDao memberDao;

    @Autowired
    private OrderDao orderDao;

    /**
     * 提交预约
     * @param paraMap
     * @return
     */
    @Override
    public Order submitOrder(Map<String, String> paraMap) throws SecurityException {
//        获取前端传入的订单日期信息
        String orderDateStr = paraMap.get("orderDate");
//        转换成跟数据一样的格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date orderDate = null;
        try {
            orderDate = sdf.parse(orderDateStr);
        } catch (ParseException e) {
//            如果转换不成功：抛异常
            throw new SunnydayException("日期格式错误");
        }
//        通过日期查询预约设置是否存在 t_ordersetting，参数为Date类型
        OrderSetting orderSetting = orderSettingDao.findByOrderDate(orderDate);
//        判断日期是否能预约
        if (null==orderSetting){
//            不存在，抛出异常
            throw new SunnydayException("所选日期，不能预约");
        }
//        存在,则判断是否是否约满
        if(orderSetting.getReservations() >= orderSetting.getNumber()) {
//            如果约满：抛异常
            throw new SunnydayException("所选日期，预约已满");
        }
//        获取前端填写的手机号码（手机号作为判断是否注册会员依据）
        String telephone = paraMap.get("telephone");
//        没有满：判断是否为会员,通过手机号码查询 t_member
        Member member = memberDao.findByTelephone(telephone);
//        判断是否为会员
        if (null==member){
//            非会员：添加到会员表 获取id
            member = new Member();
            member.setIdCard(paraMap.get("idCard"));
            member.setName(paraMap.get("name"));
            member.setPhoneNumber(telephone);
            member.setRegTime(new Date());
            member.setSex(paraMap.get("sex"));
//            添加会员, 并获取会员id
            memberDao.add(member);
        }
//        是会员：通过member_id,orderDate, setmeal_id作为条件去查询t_order表，是否重复预约
        Order order = new Order();
        order.setMemberId(member.getId());
        order.setOrderDate(orderDate);
        order.setSetmealId(Integer.valueOf(paraMap.get("setmealId")));
//        根据预约信息查询t_order表对应订单信息
        List<Order> orderList = orderDao.findByCondition(order);
//        判断是否重新预约
        if(null != orderList && orderList.size() > 0){
//            存在，重复：抛异常
            throw new SunnydayException("不能重复预约");
        }
//        补充订单信息
        order.setOrderType(Order.ORDERTYPE_WEIXIN);
        order.setOrderStatus(Order.ORDERSTATUS_NO);
//        不存在，没重复,添加订单
        orderDao.add(order);
//        更新已预约数量 t_ordersetting
        orderSettingDao.editReservationsByOrderDate(orderSetting);
        return order;
    }

    /**
     * 通过订单id查询预约信息
     */
    @Override
    public Map<String, Object> findById(Integer id) {
        return orderDao.findById(id);
    }

    @Override
    public Map<String, Object> getBusinessReportData() {
        try {
            String today = DateUtils.parseDate2String(new Date());
            String monday = DateUtils.parseDate2String(DateUtils.getThisWeekMonday());
            String sunday = DateUtils.parseDate2String(DateUtils.getSundayOfThisWeek());
            String firstDayOfThisMonth = DateUtils.parseDate2String(DateUtils.getFirstDay4ThisMonth());
            String lastDayOfThisMonth = DateUtils.parseDate2String(DateUtils.getLastDayOfThisMonth());

            Integer todayNewMember = memberDao.findMemberCountByDate(today);
            Integer thisWeekNewMember = memberDao.findMemberCountAfterDate(monday);
            Integer thisMonthNewMember = memberDao.findMemberCountAfterDate(firstDayOfThisMonth);
            Integer totalMember = memberDao.findMemberTotalCount();

            // ===============  预约统计 ===================
            //todayOrderNumber
            Integer todayOrderNumber = orderDao.findOrderCountByDate(today);
            //todayVisitsNumber
            Integer todayVisitsNumber = orderDao.findVisitsCountByDate(today);
            //thisWeekOrderNumber--
            Integer thisWeekOrderNumber = orderDao.findOrderCountBetweenDate(monday,sunday);
            //thisWeekVisitsNumber
            Integer thisWeekVisitsNumber = orderDao.findVisitsCountAfterDate(monday);
            //thisMonthOrderNumber--
            Integer thisMonthOrderNumber = orderDao.findOrderCountBetweenDate(firstDayOfThisMonth, lastDayOfThisMonth);
            //thisMonthVisitsNumber
            Integer thisMonthVisitsNumber = orderDao.findVisitsCountAfterDate(firstDayOfThisMonth);

            // ============== 热门套餐 ==================
            //hotSetmeal
            List<Map<String,Object>> hotSetmeal = orderDao.findHotSetmeal();

            Map<String, Object> map = new HashMap<String,Object>();
            map.put("reportDate",today);
            map.put("todayNewMember",todayNewMember);
            map.put("totalMember",totalMember);
            map.put("thisWeekNewMember",thisWeekNewMember);
            map.put("thisMonthNewMember",thisMonthNewMember);
            map.put("todayOrderNumber",todayOrderNumber);
            map.put("todayVisitsNumber",todayVisitsNumber);
            map.put("thisWeekOrderNumber",thisWeekOrderNumber);
            map.put("thisWeekVisitsNumber",thisWeekVisitsNumber);
            map.put("thisMonthOrderNumber",thisMonthOrderNumber);
            map.put("thisMonthVisitsNumber",thisMonthVisitsNumber);
            map.put("hotSetmeal",hotSetmeal);
            return map;

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
}
